import { and, cmp, Comparison, eq, ge, inList, le, lt, ne, outList } from 'rsql-builder'
import { isNil } from 'lodash-es'
import { RsqlDataOperatorEnum } from '@/core/utils/rsql/types/RsqlOperatorEnum'
import { like, likeRight } from '@/core/utils/rsql/rsqlExtendOperator'
import lodash from 'lodash'

class RsqlBuilder {
	private comparisons: Comparison[] = []
	static builder = () => {
		return new RsqlBuilder()
	}

	eq = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, eq(value)))
		}
		return this
	}

	like = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, like(value)))
		}
		return this
	}
	likeRight = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, likeRight(value)))
		}
		return this
	}
	ne = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, ne(value)))
		}
		return this
	}
	lt = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, lt(value)))
		}
		return this
	}
	le = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, le(value)))
		}
		return this
	}
	gt = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, lt(value)))
		}
		return this
	}
	ge = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, ge(value)))
		}
		return this
	};
	in = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, inList(value)))
		}
		return this
	}
	notIn = (name: string, value: any): RsqlBuilder => {
		if (!isNil(value)) {
			this.comparisons.push(cmp(name, outList(value)))
		}
		return this
	}
	add = (name: string, value: any, operatorEnum: RsqlDataOperatorEnum): RsqlBuilder => {
		if (operatorEnum === RsqlDataOperatorEnum.LIKE) {
			this.like(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.LIKE_RIGHT) {
			this.likeRight(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.NOT_EQUAL) {
			this.ne(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.LESS_THAN) {
			this.lt(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.LESS_OR_EQUAL) {
			this.le(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.GREATER_THAN) {
			this.gt(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.GREATER_OR_EQUAL) {
			this.ge(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.IN) {
			this.in(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.OUT) {
			this.notIn(name, value)
		} else if (operatorEnum === RsqlDataOperatorEnum.EQUAL) {
			this.eq(name, value)
		}
		return this
	}

	queryString = (): string => {
		if (lodash.isEmpty(this.comparisons)) {
			return ''
		}
		return and(...this.comparisons)
	}

	getComparisons = (): Comparison[] => {
		return this.comparisons
	}
}

export default RsqlBuilder
